﻿using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Security.Permissions;

namespace Extented.UI.Core.Helpers
{
    public static class GraphicsHelper
    {
        [ThreadStatic]
        static Bitmap staticBitmap;
        [ThreadStatic]
        static Bitmap staticHiResBitmap;
        static bool? canCreateFromZeroHwnd;
#if !SL
        static bool? canUseGetHdc;
        static bool? canUseFontSizeInPoints;
#endif
        public static bool CanCreateFromZeroHwnd
        {
            get
            {
                if (!canCreateFromZeroHwnd.HasValue)
                    try
                    {
                        using (Graphics g = CreateGraphicsFromZeroHwnd())
                            canCreateFromZeroHwnd = true;
                    }
                    catch
                    {
                        canCreateFromZeroHwnd = false;
                    }
                return canCreateFromZeroHwnd.Value;
            }
        }
#if !SL
        public static bool CanUseGetHdc
        {
            get
            {
                if (!canUseGetHdc.HasValue)
                {
                    try
                    {
                        using (Bitmap bmp = new Bitmap(1, 1))
                        {
                            using (Graphics gr = Graphics.FromImage(bmp))
                            {
                                try
                                {
                                    gr.GetHdc();
                                }
                                finally
                                {
                                    try
                                    {
                                        gr.ReleaseHdc();
                                    }
                                    catch
                                    {
                                        canUseGetHdc = false;
                                    }
                                }
                            }
                        }
                        if (!canUseGetHdc.HasValue)
                            canUseGetHdc = true;
                    }
                    catch
                    {
                        canUseGetHdc = false;
                    }
                }
                return canUseGetHdc.GetValueOrDefault();
            }
        }
        public static bool CanUseFontSizeInPoints
        {
            get
            {
                if (!canUseFontSizeInPoints.HasValue)
                {
                    try
                    {
                        using (Font font = new Font("Arial", 12, GraphicsUnit.Document))
                        {
                            float sizeInPoints = font.SizeInPoints;
                        }
                        canUseFontSizeInPoints = true;
                    }
                    catch
                    {
                        canUseFontSizeInPoints = false;
                    }
                }
                return canUseFontSizeInPoints.GetValueOrDefault();
            }
        }
#endif
        public static void ResetCanCreateFromZeroHwnd()
        {
            canCreateFromZeroHwnd = null;
        }
        public static Graphics CreateGraphicsWithoutAspCheck()
        {
            return CreateGraphicsCore(false);
        }
        public static Graphics CreateGraphics()
        {
            return CreateGraphicsCore(true);
        }
        static Graphics CreateGraphicsCore(bool checkAsp)
        {
            if (CanCreateFromZeroHwnd)
            {
                Graphics gr = CreateGraphicsFromZeroHwnd();
                if (checkAsp && PSNativeMethods.AspIsRunning && (gr.DpiX != 96.0 || gr.DpiY != 96.0))
                    gr.Dispose();
                else
                    return gr;
            }
            return CreateGraphicsFromImage();
        }
        static Graphics CreateGraphicsFromImage()
        {
            if (staticBitmap == null)
            {
                staticBitmap = new Bitmap(10, 10, PixelFormat.Format32bppArgb);
                staticBitmap.SetResolution(96f, 96f);
            }
            return Graphics.FromImage(staticBitmap);
        }
        public static Graphics CreateGraphicsFromHiResImage()
        {
            if (staticHiResBitmap == null)
            {
                staticHiResBitmap = new Bitmap(1, 1, PixelFormat.Format32bppArgb);
                staticHiResBitmap.SetResolution(300f, 300f);
            }
            return Graphics.FromImage(staticHiResBitmap);
        }
#if DEBUGTEST
		public static Graphics Test_CreateGraphicsFromImage() {
			return CreateGraphicsFromImage();
		}
#endif
        static Graphics CreateGraphicsFromZeroHwnd()
        {
            return Graphics.FromHwnd(IntPtr.Zero);
        }
    }
}
